<?php
/**
 * lsys orm
 * @author     Lonely <shan.liu@msn.com>
 * @copyright  (c) 2017 Lonely <shan.liu@msn.com>
 * @license    http://www.apache.org/licenses/LICENSE-2.0
 */
namespace LSYS\ORMCache\Lists\Cache;
use LSYS\Config;
use LSYS\Core;
use LSYS\ORM\Exception;
use LSYS\ORMCache\Lists\Result;
use LSYS\ORM;
use LSYS\ORM\Entity;
use LSYS\ORMCache\Lists\CacheGet;
use LSYS\ORMCache\Cache;
use LSYS\ShareSphinxClient;
use LSYS\ShareSphinxClient\SphinxClientShare;
abstract class Sphinx implements CacheGet, ShareSphinxClient{
	use SphinxClientShare;
	/**
	 * @var \SphinxClient
	 */
	protected $_sphinx;
	/**
	 * @var ORM
	 */
	protected $_orm;
	/**
	 * @var Cache
	 */
	protected $_cache;
	
	//标记删除字段
	public static $delete_field="_is_delete_";
	/**
	 * @param ORM $orm
	 * @param Config $config
	 */
	public function __construct(ORM $orm,Cache $cache=null,Config $config=null){
		$this->_orm=$orm;
		$this->_cache=$cache===null?Cache::instance():$cache;
		$this->_sphinx=self::get_share_sphinxclient($config);
	}
	/**
	 * @var array
	 */
	private $_cache_total=array();
	/**
	 * {@inheritDoc}
	 * @see \LSYS\ORMCache\Lists\CacheGet::lists_get()
	 */
	public function lists_get(array $where,$sort,$offset,$limit){
		is_null($sort)&&$sort=array();
		is_string($sort)&&$sort=array($sort);
		$ids=$this->_query($where,$sort,$offset,$limit);
		return new Result($this->_orm, $ids,$this->_cache);
	}
	/**
	 * {@inheritDoc}
	 * @see \LSYS\ORM\Lists::lists_total()
	 */
	public function lists_total_get(array $where){
		if (!isset($this->_cache_total[json_encode($where)]))$this->_query($where,array());
		return $this->_cache_total[json_encode($where)];
	}
	public function lists_insert(Entity $entity){
		return ;
	}
	public function lists_update(Entity $new_entity){
		return ;
	}
	public function lists_delete(Entity $entity){
		$id=intval($pk);
		if ($id==0) return true;
		$this->_sphinx->UpdateAttributes ($this->_lists_index(), array(self::$delete_field), array($id=>array(1)) );
	}
	/**
	 * query shpinx
	 * @param array $where
	 * @param string $sort
	 * @param number $offset
	 * @param number $limit
	 * @throws Exception
	 * @return string[]
	 */
	protected function _query(array $where,array $sort,$offset=0,$limit=1){
		ksort($where);
		$sphinx=$this->_sphinx;
		$sphinx->ResetFilters();
		$this->_lists_where($where, $sort,$primary_key);
		$sphinx->SetLimits ( $offset, $limit );
		$sphinx->SetFilter ( self::$delete_field, array(0) );
		$result = $sphinx->query('',$this->_lists_index());//查询
		if (!$result||isset($result['error'])){
			if(Core::$is_windows) $msg=iconv("GB2312","UTF-8",$s->GetLastError());
			else $msg=$s->GetLastError();
			throw new Exception($msg);
		}
		if (!is_array(@$result['matches'])) return array();
		$ids=array();
		$total=($result['total_found']>$result['total']?$result['total']:$result['total_found']);
		$this->_cache_total[json_encode($where)]=$total;
		foreach ($result['matches'] as $v){
			$ids[]=$v[$primary_key];
		}
		return $ids;
	}
	/**
	 * @return string
	 */
	protected function _lists_index(){
		$cls=get_called_class ();
		$pos=strrpos($cls,"\\");
		return substr($cls,$pos===false?0:$pos+1,-3);
	}
	/**
	 * list pro..
	 * @param array $where
	 * @param string $sort
	 * @param int $primary_key ref pk key
	 * @return string index
	 */
	abstract protected function _lists_where(array $where,array $sort,&$primary_key='id');
} 